package com.rgsx.dao;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.rgsx.data.DataPool;
import com.rgsx.entiy.Position;
import com.rgsx.mapper.OrderMapper;
import com.rgsx.mapper.UserMapper;
import com.rgsx.pojo.Order;
import com.rgsx.utils.RedisPositionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.Date;

@Repository
public class OrderDao {

    @Resource
    private RedisTemplate redisTemplate;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserMapper userMapper;

    private Logger logger = LoggerFactory.getLogger(OrderDao.class);

    public Long OrderOrigination(Long passengerId, Position positionStart,Position positionEnd){
        Order order = new Order(null,
                null,
                passengerId,
                new Date(),
                0,
                null,
                positionStart.getPositionLatitude(),
                positionEnd.getPositionLatitude(),
                positionStart.getPositionLongitude(),
                positionEnd.getPositionLongitude());
        try {
            int successNum = orderMapper.insert(order);
            if(successNum < 1){
                return null;
            }
            redisTemplate.opsForValue().set("order:" + order.getId(),order);


            //写入redis GEO类型
            if(RedisPositionUtil.setGeoToRedis(redisTemplate,order.getId(),positionStart))
                return order.getId();
            else throw new Exception();
        } catch (Exception e) {
            //回滚 尝试3次回滚
            int callBackNum = 3;

            while (callBackNum-- > 0){
                logger.info("---开始回滚,还剩" + callBackNum -- + "次回滚机会");
                Object o = redisTemplate.opsForValue().get("order:" + order.getId());
                if(o == null){
                    //成功删除
                    int num = orderMapper.deleteById(order.getId());
                    if(num > 0){
                        logger.info("-----回滚成功-----");
                        break;
                    }
                    continue;
                }
                Boolean isSuccess = redisTemplate.delete("order:" + order.getId());
                if(isSuccess) return null;

                try {
                    Thread.currentThread().wait(5000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            return null;
        }
    }

    //检查是否有订单未完成
    public Order checkIsHaveOrderNotDone(long passengerId){
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("passenger_id",passengerId);
        wrapper.in("state",0,1,2);
        Order order = orderMapper.selectOne(wrapper);
        return order;
    }

    public Order ReceivingOrders(long orderId,long driverId){
        //拿到订单
        Order order = (Order) redisTemplate.opsForValue().get("order:" + orderId);
        if(order == null){
            logger.info("=====司机接收乘客上车=====");
            logger.info("=====redis的订单信息过期======");
            //查询数据库
            order = orderMapper.selectById(orderId);
            if(order == null)return null;
        }
        order.setState(1);
        order.setDriverId(driverId);

        //写入数据库
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id",orderId);
        int isSucess = orderMapper.update(order, updateWrapper);
        if(isSucess < 1)return null;
        //写入缓存
        redisTemplate.opsForValue().set("order:" + orderId,order);
        //删除redis位置信息
        redisTemplate.opsForGeo().remove(DataPool.KEY,"order:" + order.getId());

        return order;
    }

    public Order GetOnTheCar(long orderId){
        //拿到订单
        Order order = (Order) redisTemplate.opsForValue().get("order:" + orderId);
        if(order == null){
            logger.info("=====司机接收乘客上车=====");
            logger.info("=====redis的订单信息过期======");
            //查询数据库
            order = orderMapper.selectById(orderId);
            if(order == null)return null;
        }
        order.setState(2);
        //写入数据库
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id",orderId);
        int isSucess = orderMapper.update(order, updateWrapper);
        if(isSucess < 1)return null;
        //写入缓存
        redisTemplate.opsForValue().set("order:" + orderId,order);
        redisTemplate.opsForGeo().remove(DataPool.KEY,"order:" + orderId);

        logger.info("=====司机接收乘客上车=====");
        logger.info("=====重新写入双数据库======");
        logger.info(order.toString());
        return order;
    }

    public boolean orderOver(long orderId){
        Boolean isSuccess = redisTemplate.delete("order:" + orderId);
        if(isSuccess){
            logger.info("===结束订单===");
            logger.info("结束订单时，缓存过期");
            logger.info("===结束订单===");
        }
        UpdateWrapper<Order> wrapper = new UpdateWrapper<>();
        wrapper.eq("id",orderId);
        wrapper.set("state",3);
        int num = orderMapper.update(null, wrapper);

        return num > 0;
    }

}
